#!groovy
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

@NonCPS
def getDefaultTag() {
    LocalDateTime localDateTime = LocalDateTime.now()
    localDateTime.format(DateTimeFormatter.ofPattern('yyyyMMddHHmmss', Locale.CHINESE))
}

def call(String type, Map map) {

    // 镜像名称：镜像前缀+项目名
    def imageName = "legendarys/" + "${map.applicationName}"

    // 镜像tag，默认是时间戳
    def imageTag = getDefaultTag()

    if (type == "maven") {
        pipeline {
            agent any

            parameters {
                // 部署的代码git分支，默认master
                string(name: 'repoBranch', defaultValue: "${map.repoBranch}", description: 'git分支名称')
                // pom.xml的相对路径
                string(name: 'pomPath', defaultValue: 'pom.xml', description: 'pom.xml的相对路径')
                // 单元测试代码覆盖率要求，各项目视要求调整参数
                string(name: 'lineCoverage', defaultValue: '20', description: '单元测试代码覆盖率要求(%)，小于此值pipeline将会失败！')
            }

            //环境变量，初始确定后一般不需更改
            tools {
                maven "maven3.5"
                jdk "jdk8"
            }

            //常量参数，初始确定后一般不需更改
            environment {
                //pom.xml的相对路径
                POM_PATH = "${map.POM_PATH}"
                // 代码仓库地址
                REPO_URL = "${map.REPO_URL}"
                // 代码仓库的只读账号
                CRED_ID = "${map.CRED_ID}"
            }

            options {
                disableConcurrentBuilds()
                timeout(time: 1, unit: 'HOURS')
                //保持构建的最大个数
                buildDiscarder(logRotator(numToKeepStr: '10'))
            }

            //pipeline的各个阶段场景
            stages {
                stage('代码获取') {
                    steps {
                        //一些初始化操作
                        script {
                            echo "starting fetchCode from ${REPO_URL}......"
                            // 多分支构建可以使用 checkout scm
                            checkout scm
                            // git credentialsId: CRED_ID, url: REPO_URL, branch: params.repoBranch
                        }
                    }
                }

                stage('单元测试') {
                    steps {
                        echo "starting unitTest......"
                        // 命令行引用jacoco插件依赖,clean test执行单元测试代码.
                        sh "mvn org.jacoco:jacoco-maven-plugin:prepare-agent -f ${params.pomPath} clean test -Dautoconfig.skip=true -Dmaven.test.skip=false -Dmaven.test.failure.ignore=true"
                        junit '**/target/surefire-reports/*.xml'
                        // 配置单元测试覆盖率要求，未达到要求pipeline将会fail,code coverage.LineCoverage>20%.
                        jacoco changeBuildStatus: true, maximumLineCoverage: "${params.lineCoverage}"
                    }
                }

                stage('静态检查') {
                    steps {
                        echo "starting codeAnalyze with SonarQube......"
                        // sonar:sonar.QualityGate should pass
                        // withSonarQubeEnv('SonarQube') {
                        // 固定使用项目根目录${basedir}下的pom.xml进行代码检查
                        // sh "mvn -f pom.xml clean compile sonar:sonar"
                        // }
                        // script {
                        // timeout(10) {
                        // 利用sonar webhook功能通知pipeline代码检测结果，未通过质量阈，pipeline将会fail
                        // def qg = waitForQualityGate()
                        // if (qg.status != 'OK') {
                        // error "未通过Sonarqube的代码质量阈检查，请及时修改！failure: ${qg.status}"
                        // }
                        // }
                        // }
                    }
                }

                stage('docker build') {
                    steps {
                        sh "mvn clean package -U -Dmaven.test.skip=true -Dimage_name=${imageName} docker:build"
                    }
                }

                stage('docker tag & docker push') {
                    steps {
                        // 也可以执行脚本来打tag，推送镜像
                        // sh "docker tag ${imageName} ${imageName}:${imageTag}"
                        // sh "docker push ${imageName}:${imageTag}"
                        script {
                            // 这种方式是通过Jenkins提供的全局变量docker来操作的，更加面向程序员
                            def image = docker.image(imageName)
                            image.tag(imageTag)
                            image.push(imageTag)
                        }
                    }
                }

                stage('completed') {
                    steps {
                        echo 'deploy completed'
                        cleanWs()
                    }
                }
            }
        }
    } else if (type == "gradle") {
        // gradle 的处理方式
    }
}
